<?php
declare (strict_types = 1);

namespace app\admin\model\system;

use bbweb\traits\ModelTrait;
use bbweb\basic\BaseModel;

/**
 *菜单类
 */
class SystemMenus extends BaseModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 模型名称
     * @var string
     */
    protected $name = 'system_menus';

    use ModelTrait;

    // 设置字段信息
    protected $schema = [
        'id'	        => 'int',
        'pid'           => 'int',
        'type'          => 'tinyint',
        'icon'          => 'varchar',
        'menu_name'     => 'varchar',
        'url'           => 'varchar',
        'controller'    => 'varchar',
        'action'        => 'varchar',
        'sort'          => 'tinyint',
        'visable'       => 'tinyint',
        'is_show'       => 'tinyint'
    ];
    /**
     * @param $controller
     * @param $action
     * @param array $auth
     * @return array
     */
    public static function getSonAuth($controller, $action, $auth = [])
    {
        $pid = self::where('action', $action)
            ->where('controller', $controller)
            ->value('id');
        if(!$pid) return [];
        return self::where(['pid' => $pid,'visable'=>1])->where('id', 'IN', $auth)->order('id ASC')->column('id','action');
    }


    /**
     * @return array|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \Exception
     */
    public static function menuList()
    {
        $menusList = self::where('is_show', '1')->where('visable', '1')->order('sort ASC,id ASC')->select();
        return self::tidyMenuTier(true, $menusList);
    }


    /**
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function menuAll()
    {
        $menuAll = self::order('sort ASC,id ASC')->select();
        return self::tidyMenuTree($menuAll);
    }


    /**
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \Exception
     */
    public static function ruleList()
    {
        $ruleList = self::where('visable', '1')->order('sort ASC,id ASC')->select();
        return self::tidyMenuTier(false, $ruleList);
    }

    /**
     * @param $roleid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function rolesByRuleList($roleid)
    {
        $res = SystemRole::where('id', $roleid)->field('GROUP_CONCAT(roles) as ids')->find();
        $ruleList = self::where('id', 'IN', $res['ids'])->whereOr('pid', 0)->where('visable', '1')->order('sort DESC')->select();
        return self::tidyMenuTier(false, $ruleList);
    }

    /**
     * @param $action
     * @param $controller
     * @return string
     */
    public static function getAuthName($action, $controller)
    {
        if(empty($action)) return '/' . $controller;
        else return  '/' . $controller . '/' . $action;
    }

    /**
     * @param $adminFilter
     * @param $menusList
     * @param int $pid
     * @param array $navList
     * @return array|mixed
     * @throws \Exception
     */
    public static function tidyMenuTier($adminFilter, $menusList, $pid = 0, $navList = [])
    {
        static $allAuth = null;
        static $adminAuth = null;
        if ($allAuth === null) $allAuth = $adminFilter == true ? SystemRole::getAllAuth() : [];//所有的菜单
        if ($adminAuth === null) $adminAuth = $adminFilter == true ? SystemAdmin::activeAdminAuthOrFail() : [];//当前登录用户的菜单
        foreach ($menusList as $k => $menu) {
            $menu = $menu->getData();
            if ($menu['pid'] == $pid) {
                unset($menusList[$k]);
                $authName = self::getAuthName($menu['action'], $menu['controller']);// 按钮链接
                if ($pid != 0 && $adminFilter && in_array($authName, $allAuth) && (!in_array($authName, $adminAuth) || !array_key_exists($menu['id'], $adminAuth))) continue;
                $menu['child'] = self::tidyMenuTier($adminFilter, $menusList, $menu['id']);
                if ($pid != 0 && !count($menu['child']) && !$menu['controller'] && !$menu['action']) continue;
                if ($pid == 0 && !count($menu['child'])) continue;
                $navList[] = $menu;
            }
        }
        return $navList;
    }

    /**
     * @param $menusList
     * @param int $pid
     * @param array $navList
     * @return array
     */
    public static function tidyMenuTree($menusList, $pid = 0, $navList = [])
    {
        foreach ($menusList as $k => $menu) {
            $menu = $menu->getData();
            if ($menu['pid'] == $pid) {
                unset($menusList[$k]);
                $navList[] = $menu;
                $navList = self::tidyMenuTree($menusList, $menu['id'],$navList);
            }
        }
        return $navList;
    }

    /**
     * @param $id
     * @return bool
     */
    public static function delMenu($id)
    {
        if (self::where('pid', $id)->count())
            return self::setErrorInfo('请先删除该菜单下的子菜单!');
        return self::del($id);
    }
}
